Observable与Alamofire

Observable

Observable也就是一个被观察的对象,是一个事件序列,订阅者可以订阅它,监测事件的发生(Next\Complete\Error)。是不是听到这里就感觉这货有点像KVO?

热信号vs冷信号

信号分两种,热信号在它创建的时候就开始推送事件,这意味着如果后面有订阅者来的时候,就可能会错过一些事件。而冷信号则不会,只有在它被订阅的时候,它才会发送事件,这可以保证后面即使有订阅者中途加入的时候也能收到完整的事件序列。

获得Observable

要得到一个Observable有两种方式,一种是RxSwift已经提供了的(这里你可能需要引入RxCocoa),一种是自己创建。比如你有一个UITextfield,你要订阅其text的变化,就可以通过textfield.rx_text来获得这个Observable的对象。如果要自己创建的话,可以利用它提供的create函数来创建,create接受函数闭包作为参数,比如我的项目里用到了Alamofire,我如果想让它的response是一个observable的,我可以这样写:

    func fetchClubList(fromPage page:Int) -> Observable<[ClubTableCellViewModel]>{

        return create{ (observer ) -> Disposable in
            Alamofire.request(Method.GET, "http://www.mocky.io/v2/560a046995e00cc208981280").responseArray{[unowned self]
                 (results:[ClubModel]?, err:ErrorType?) -> Void in
                    if let _ = err{
                        observer.on(Event.Error(err!))
                    }else{
                        if let cellVMs = (results?.map{ClubTableCellViewModel(club: $0)}){
                            if page == 0{
                                self.cellViewModels.removeAll()
                            }
                            self.cellViewModels.appendContentsOf(cellVMs)

                            observer.on(Event.Next(self.cellViewModels))
                            observer.on(Event.Completed)
                        }else{
                            //TODO: error handle
                        }
                    }
                }

            return NopDisposable.instance
        }
    }

这样就创建了一个Observable<[ClubModel]>,当他上面有事件发生的时候,我们可以做相应的操作。除了create,还可以通过never()创建一个什么都不发送的空序列,用empty()创建一个空序列但会发送.Complete等等。

信号的操作

常用的操作符有map,flatMap,subscribe,doOn,retry等等,具体的用法在它的文档中有具体说明。比如在我的demo里,需要根据页码加载列表数据。可以像这样做,在我的UIViewController里先创建一个属性:

var page : Variable<Int> = Variable(0)

接下来订阅这个page

    self.page
        .throttle(0.5, MainScheduler.sharedInstance)
        .doOn{ [unowned self] value in
            self.refreshCtrl.enabled = false
        }
        .flatMap {[unowned self] in
            self.viewModel.fetchClubList(fromPage: $0)
                .doOn{ [unowned self] in
                    self.refreshCtrl.endRefreshing()
                    self.refreshCtrl.enabled = true
                }
                .retry()
                .catchErrorJustReturn([])
        }
        .bindTo(self.clubList.rx_itemsWithCellIdentifier("clubCell")){(_, viewModel, cell: ClubListCell) in
            cell.viewModel = viewModel
        }
        .addDisposableTo(self.dispose)

这段代码里实现了在page发生变化的时候自动去请求服务端的数据,然后刷新tableview。throttle保证了事件序列发送的频率不会过快,doOn在每次.Next到来之前让我们有机会做些额外的处理,页码变化通过flatMap触发API调用,然后把得到的数据绑定到每个cell上面。

通过RxSwift整个代码量减少了很多,也变得更加易读,是不是感觉很棒!现在了解的也不够多,欢迎大家一起来交流

func getSprites() -> Observable<AnyObject?> {
        return create{ observer in
            var request = Alamofire.request(.GET, "https://epoquecore.com/sprites", parameters: nil)
                .response({ (request, response, data, error) in
                    if((error) != nil){
                        sendError(observer, error!);
                    }else{
                        sendNext(observer, data);
                        sendCompleted(observer);
                    }
                });
            return AnonymousDisposable {
                request.cancel()
            }
        }
    }

results matching ""

    No results matching ""